using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    /// <summary>
    /// 所有真实存在的实体基类，只做一些最基本的封装抽象
    /// 扩展以Component组件化方式
    /// </summary>
    public abstract class LevelPlayRealityEntity : LevelPlayBaseEntity
    {
        /// <summary>
        /// 对象池的GameObject实体
        /// </summary>
        private Entity _objectEntity;
        private TransformAgent _transform;
        /// <summary>
        /// gameObject下名为"model"的子节点
        /// </summary>
        private Transform _modelTransform;
        private AnimatorAgent _animator;

        public override TransformAgent transform => _transform;
        public GameObject gameObject => _transform.gameObject;
        public override float defaultMeterSpeed => GameMathUtil.LogicValue2Float(GetDefaultSpeed());
        /// <summary>
        /// 交互指示器是否正显示在头上
        /// </summary>
        public bool isIndicatorOnMe { get; private set; }

        /// <summary>
        /// 实体加载路径
        /// </summary>
        /// <returns></returns>
        protected abstract string GetEntityLoadPath();

        public virtual async UniTask LoadAndInstantiate(Transform holder)
        {
            var entityResPath = GetEntityLoadPath();
            _objectEntity = ManagerCenter.Entity.Get(entityResPath, (int)EntityPoolGroupType.LevelEntity);
            EntityLoadState state = await _objectEntity.Load();

            if (_objectEntity.gameObject == null)
            {
                return;
            }
            var gameObject = _objectEntity.gameObject;
#if UNITY_EDITOR
            gameObject.name = $"[{id.ToString()}][{GetDynLevelEntity()?.levelEntityConfig?.id}]{System.IO.Path.GetFileNameWithoutExtension(entityResPath)}";
#endif
            _transform = ClassPool.Get<TransformAgent>();
            _transform.Value = gameObject.transform;
            _transform.SetParent(holder);
            _transform.localRotation = GameMathUtil.IntEuler2Quaternion(this.dirEuler);
            var dynEntity = GetDynEntityData();
            _transform.position = dynEntity.isIgnoreGroundAdjust ? GameMathUtil.LogicPos2UnityPos(x, y, z) : LevelPlayUtil.GetAdjustedPosByGround(x, y, z);

            _modelTransform = _transform.Find("model");
            if (_modelTransform == null)
            {
                _modelTransform = _transform;
            }

            var entityDriver = gameObject.GetComponent<EntityDriver>();
            if (entityDriver != null)
            {
                entityDriver.defaultAudioSheet = cfgEntity.DefaultAudioSheet;
            }

            //广播事件
            BroadcastComponentEvent(TComponentEvent.OnEntityObjectLoaded, state);
        }

        public override void OnEntityBirth()
        {
            //bool result = LevelPlayManager.Instance.levelPlay.navigationCtrl.FindNearestPoint(transform.position, out var realEndPos);
            //if (!result)
            //{
            //    LogGame.LogError($"Level Entity can't find NearestPoint,entityId:{id} pos:{transform.position.ToString()}");
            //    return;
            //}
            //this.transform.position = realEndPos;
        }

        public void GetTransformPosXZ(out float x, out float z)
        {
            var pos = transform.position;
            x = pos.x;
            z = pos.z;
        }

        /// <summary>
        /// 把transform的位置刷新给数据
        /// 用于服务器不同步位置的纯客户端移动
        /// </summary>
        public void TransPosToData()
        {
            if (transform != null)
            {
                var data = GetDynEntityData();
                Vector3 v3 = GameMathUtil.UnityPos2LogicPos(transform.position);
                data.UpdatePos(v3.x, v3.y, v3.z);
            }
        }

        protected void TryHideEntity()
        {
            if (_objectEntity != null)
            {
                ManagerCenter.Entity.HideEntity(_objectEntity);
                _objectEntity = null;
                BroadcastComponentEvent(TComponentEvent.OnEntityObjectHided);
            }
        }

        public override AnimatorAgent GetAnimator()
        {
            if (_animator != null)
            {
                return _animator;
            }
            _animator = ClassPool<EventAnimator>.Get();
            var anim = _modelTransform.GetComponent<Animator>();
            if (anim != null) //anim == null时，并非真正的null，所以这里最好不要直接赋值，要先做非空判断
            {
                _animator.animator = anim;
            }
            return _animator;
        }

        public virtual void OnIndicatorChange(bool isIndicatorOnMe)
        {
            this.isIndicatorOnMe = isIndicatorOnMe;
        }

        public override void Free()
        {
            TryHideEntity();
            base.Free();
        }

        public override void OnReset()
        {
            base.OnReset();
            _modelTransform = null;
            if (_transform != null)
            {
                ClassPool.PutAutoType(_transform);
                _transform = null;
            }
            if (_animator != null)
            {
                ClassPool.PutAutoType(_animator);
                _animator = null;
            }
            isIndicatorOnMe = false;
        }
    }
}
